package com.tpvlog.dfs.client;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import java.io.File;

/**
 * 文件系统客户端的实现类
 *
 * @author Ressmix
 */
public class FileSystemImpl implements FileSystem {

    private NameNodeRpcClient rpcClient = new NameNodeRpcClient();

    public void mkdir(String path) throws Exception {
        rpcClient.mkdir(path);
    }

    public Boolean upload(byte[] file, String filename, long fileSize) throws Exception {
        // 1.RPC接口发送文件元数据
        if (!filename.startsWith(File.separator)) {
            filename = File.separator + filename;
        }
        if (!rpcClient.createFile(filename)) {
            return false;
        }

        // 2.RPC接口获取DataNode
        String datanodesJson = rpcClient.allocateDataNodes(filename, fileSize);
        System.out.println(datanodesJson);
        if (datanodesJson == null) {
            return false;
        }

        // 3.遍历DataNode，依次上传文件
        JSONArray datanodes = JSONArray.parseArray(datanodesJson);
        for (int i = 0; i < datanodes.size(); i++) {
            JSONObject datanode = datanodes.getJSONObject(i);
            String hostname = datanode.getString("hostname");
            int nioPort = datanode.getIntValue("nioPort");
            DFSNIOClient.sendFile(hostname, nioPort, file, filename, fileSize);
        }
        return true;
    }

    public byte[] download(String filename) throws Exception {
        // 1.获取待下载文件对应的可用DataNode节点
        String datanode = rpcClient.getDataNodeForFile(filename);
        System.out.println("NameNode分配用来下载文件的数据节点：" + datanode);

        // 2.解析DataNode信息
        JSONObject jsonObject = JSONObject.parseObject(datanode);
        String hostname = jsonObject.getString("hostname");
        Integer nioPort = jsonObject.getInteger("nioPort");

        // 3.基于Java NIO下载文件
        return DFSNIOClient.readFile(hostname, nioPort, filename);
    }

    public void shutdown() throws Exception {
        rpcClient.shutdown();
    }
}
